通常情况下, 类似于数据源, 事务, 整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中)。放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao。所以 Spring 的加载要在 SpringMVC 之前。即 DispatcherServlet 之前。所以我们可以在监听器里面创建 Spring 对象。
配置监听器
配置一个监听器,让其在 contextInitialized 的时候加载 Spring 的配置文件,创建 Spring IOC 容器。
我们在 Controller 中看是否能获取 Spring 管理的对象。如果能就说明二者的整合没问题(Controller 是 SpringMVC 管理,其余对象是 Spring 管理,在 Controller 中能获取 Spring 管理的对象,那就说明没问题。)
在创建监听器的时候,将 SpringIOC 容器塞入 ServletContext 中
1 2 3 4 5 6 7 8 9
@Override publicvoidcontextInitialized(ServletContextEvent sce){ // 创建 Spring IOC 容器对象 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); // 可以将创建的 applicationContext 对象放入 ServletContext 中,以便在后续中 // 可以随时获取 Spring 管理的对象 ServletContext servletContext = sce.getServletContext(); servletContext.setAttribute("applicationContext", applicationContext); }
在 Controller 中进行获取 Spring 管理的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Controller publicclassTestController{ @ResponseBody @RequestMapping("/testListaner") public User testListaner(HttpSession session){ // 从 HttpSession 中获取 ServletContext 对象 ServletContext servletContext = session.getServletContext(); // 从 ServletContext 中获取 Spring IOC 对象(我们在监听器中将 Spring IOC 对象存放在了 ServletContext 中) ApplicationContext applicationContext = (ApplicationContext) servletContext.getAttribute("applicationContext"); // 从 Spring IOC 中获取 Spring 管理的 user 对象 User user = applicationContext.getBean("user", User.class); return user; } }
使用自带监听器进行 Spring 和 SpringMVC 的整合
上面我们是自己创建了一个监听器,然后在监听器中创建 Spring IOC 容器,但是 Spring 官方给我们提供了一个监听器,可以直接使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<!-- 手动创建 listener。listener 中创建 Spring IOC 容器 --> <!-- <listener> <listener-class>com.atguigu.listener.SpringListener</listener-class> </listener> -->
<!-- 使用 Spring自带的监听器创建 Spring IOC --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 指定 Spring 配置文件的位置。默认会去找 WEB-INF 下的 applicationContext.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param>
@Controller publicclassTestController{ @ResponseBody @RequestMapping("/testListaner") public String testListaner(HttpSession session){ /** // 从 HttpSession 中获取 ServletContext 对象 ServletContext servletContext = session.getServletContext(); // 从 ServletContext 中获取 Spring IOC 对象(我们在监听器中将 Spring IOC 对象存放在了 ServletContext ) ApplicationContext applicationContext = (ApplicationContext) servletContext.getAttribute("applicationContext"); // 从 Spring IOC 中获取 Spring 管理的 user 对象 User user = applicationContext.getBean("user", User.class); **/ return"success"; } }
Spring IOC 容器和 SpringMVC IOC 容器的关系
Spring IOC 容器是父容器,SpringMVC IOC 容器是子容器。子容器能够调用访问父容器中的 bean,而父容器不能调用访问子容器的 bean。
也就是说 Controller 中能够访问 Service bean 和 Dao bean。但是 Service 或 Dao 不能调用 Controller bean。